package edu.towson.cosc.cosc455.cbrown.mdcomp;

import edu.towson.cosc.cosc455.interfaces.LexicalAnalyzer;
import java.util.Vector;

public class MyLexAnalyzer implements LexicalAnalyzer {
	
	private Vector<String> TOKENS;
	private static String sourceFile;
	private int position;
	private char nextChar;
	private String token;
	boolean endReached;
	
	public void start(String line) throws CompilerException{
		sourceFile = line;
		position = 0;
		TOKENS = new Vector<String>();
		endReached = false;
		
		//All legal tokens
		TOKENS.add("#START DOCUMENT"); TOKENS.add("#END DOCUMENT");
		TOKENS.add("#START HEAD"); TOKENS.add("#END HEAD");
		TOKENS.add("#START TITLE"); TOKENS.add("#END TITLE");
		TOKENS.add("#START PARAGRAPH"); TOKENS.add("#END PARAGRAPH");
		TOKENS.add("#START BOLD"); TOKENS.add("#END BOLD");
		TOKENS.add("#START ITALICS"); TOKENS.add("#END ITALICS");
		TOKENS.add("#START LIST"); TOKENS.add("#END LIST");
		TOKENS.add("#START ITEM"); TOKENS.add("#END ITEM");
		TOKENS.add("#START AUDIO"); TOKENS.add("#END AUDIO");
		TOKENS.add("#START VIDEO"); TOKENS.add("#END VIDEO");
		TOKENS.add("#START DEFINE"); TOKENS.add("#END DEFINE");
		TOKENS.add("#START USE"); TOKENS.add("#END USE");
		TOKENS.add("#NEWLINE");
		TOKENS.add("#NAME");
		TOKENS.add("#VALUE");
		
		
		getCharacter();
		getNextToken();
	}
	
	//Gets next token and places it in MyCompiler's token
	//Checks to see if text or actual token
	public void getNextToken() throws CompilerException{
		if (endReached) {
			MyCompiler.token = null;
			return;
		}
		
		token = "";
		
		if(nextChar != '#' && nextChar != '\n' && nextChar != '\t' && !isSpace(nextChar)) {
			while(nextChar != '#' && !endReached) {
				if(nextChar != '\n' && nextChar != '\t') {
					addCharacter();
					getCharacter();
				}
				else
					getCharacter();
			}
			
			MyCompiler.token = token;
		}
		
		else if(nextChar == '\n' || nextChar == '\t' || isSpace(nextChar)){
			getCharacter();
			getNextToken();
		}
			
		
		else {	
			while(!isSpace(nextChar) && !endReached) {
				addCharacter();
				getCharacter();
			}
			
			if(lookupToken()){
				MyCompiler.token = token;
				
				if(nextChar == ' ') //Deletes space after tag
					getCharacter();
			}
			
			else if(token.equalsIgnoreCase("#Start") || token.equalsIgnoreCase("#End")) {
				addCharacter();
				getCharacter();
				
				while(!isSpace(nextChar) && !endReached) {
					addCharacter();
					getCharacter();
				}
				
				if(lookupToken()){
					MyCompiler.token = token;
					
					if(nextChar == ' ') //Deletes space after tag
						getCharacter();
				}
				else {
					String m = token + " is an invalid token.";
					throw new CompilerException(m);
				}
			}
			
			else {
				String m = token + " is an invalid token.";
				throw new CompilerException(m);
			}
		}
	}

	//Gets next character and adds to nextChar. Also checks to see if the end of the file has been reached
	public void getCharacter() {
		if (position < sourceFile.length()) 
			nextChar = sourceFile.charAt(position++);
		else {
			endReached = true;
			return;
		}
	}

	//Adds next character to token
	public void addCharacter() {
		token += nextChar;

	}

	//Checks to see if char is space
	public boolean isSpace(char c) {
		if (c == ' ')
			return true;
		else
			return false;
	}

	//Checks to see if token is legal
	public boolean lookupToken() {
		if (token != null) {
			if (TOKENS.contains(token.toUpperCase()))
				return true;
			else
				return false;
		}
		else
			return false;
	}

}
